//
// Created by xiexiangping on 23-04-12
//
#include "frameOperate.h"

cv::Mat frameOperate::avframe_to_cvmat_yuyv(AVFrame* frame)
{
    // 检查输入参数
    assert(frame);
    assert(frame->format == AV_PIX_FMT_YUYV422);

    // 转换图像的宽度和高度
    int width = frame->width;
    int height = frame->height;

    // 分配目标图像的内存
    cv::Mat dst_mat(height, width, CV_8UC3);

    // 转换参数：YUYV422 --> BGR24
    int src_linesize[1] = { width * 2 }; // YUYV422 中每个像素占2字节
    uint8_t* src_data[1] = { frame->data[0] };
    int dst_linesize[1] = { width * 3 }; // BGR24 中每个像素占3字节
    uint8_t* dst_data[1] = { dst_mat.data };
    SwsContext* sws_ctx = sws_getContext(width, height, AV_PIX_FMT_YUYV422, width, height,
                                         AV_PIX_FMT_BGR24,SWS_BILINEAR, nullptr, nullptr, nullptr);
    // 执行转换
    sws_scale(sws_ctx, src_data, src_linesize, 0, height, dst_data, dst_linesize);

    // 释放资源
    sws_freeContext(sws_ctx);

    return dst_mat.clone();
}

cv::Mat frameOperate::avframe_to_cvmat_yuvp20(AVFrame *frame) {
    // 获取 AVFrame 的宽和高
    const int width = frame->width;
    const int height = frame->height;
    // 创建一个用于存储图像数据的 cv::Mat
    cv::Mat img(height, width, CV_8UC3);
    // 初始化一个 SwsContext，用于转换图像格式
    SwsContext *sws_ctx = sws_getContext(width, height, AV_PIX_FMT_YUV420P, width, height, AV_PIX_FMT_BGR24, 0, nullptr, nullptr, nullptr);
    // 检查 sws_ctx 是否创建成功
    if (!sws_ctx) {
        fprintf(stderr, "Failed to create SwsContext for AVFrame to cv::Mat conversion");
        return cv::Mat();
    }
    // 为 cv::Mat 分配内存，将 AVFrame 中的图像数据复制到 cv::Mat 中
    uint8_t *data[AV_NUM_DATA_POINTERS] = {0};
    int linesize[AV_NUM_DATA_POINTERS] = {0};
    data[0] = img.data;
    linesize[0] = img.step;
    sws_scale(sws_ctx, frame->data, frame->linesize, 0, height, data, linesize);
    // 释放 SwsContext
    sws_freeContext(sws_ctx);
    return img.clone();
}
